package fang365

import (
	"encoding/json"
	"github.com/xiaobaiskill/fang/internal/proxypool"
	"github.com/xiaobaiskill/fang/internal/websocket"
	"github.com/xiaobaiskill/fang/pkg/models"
	"io"
	"io/ioutil"
	"net/http"
	"github.com/xiaobaiskill/fang/pkg/log"
	"fmt"
	"strconv"
	"time"
)

var (
	fang_phone_url = `https://mtsapi.house365.com/secure/?method=secondhouse.getHouseDetail&city=%s&client=tf&version=8.0.90&v=8.0.90&commitId=ed9b136&api_key=android&name=HouseSell&id=%s&app=sell`
)

type fangInfoPhone struct {
	fanginfo FangInfo  // 信息
	result chan bool
}

func (f *fangInfoPhone) Execute(){
	var (
		err        error
		resp       *http.Response
		clientMap  proxypool.HTTPClientMap
		httpclient *http.Client
		index      int
		ok         bool
		retryMax   int = 2
	)
	proxypools := proxypool.Newproxypools()
	req, _ := http.NewRequest("GET", fmt.Sprintf(fang_phone_url, f.fanginfo.City, f.fanginfo.Id), nil)

	for {
		clientMap, index, ok = proxypools.Pop()
		if !ok {
			f.result <- false
			return
		}
		retryMax = 2 // 重置单个IP重试次数
		//log.Logger.Info("[getfangphone] 使用的代理ip为：" + clientMap.Ip)
		httpclient = clientMap.Client

		for {
			resp, err = httpclient.Do(req)
			checkOk := f.retryPolicy(resp, err)

			if !checkOk {
				go func(i int, cm proxypool.HTTPClientMap) { proxypools.Push(i, cm) }(index, clientMap)
				f.transformSend(resp)
				return
			}

			if err == nil {
				f.drainBody(resp.Body)
			} else {
				//log.Logger.Error(fmt.Sprintf("[getfangphone]  代理IP：%s,请求失败：%v", clientMap.Ip, err))
				go func(i int, cm proxypool.HTTPClientMap) { proxypools.Del(i, cm) }(index, clientMap)
				break
			}

			retryMax--
			// 单个代理ip的使用次数用完了 ，但是还是没有获取到数据，则结束这个ip ,用下一个
			if retryMax <= 0 {
				go func(i int, cm proxypool.HTTPClientMap) { proxypools.Push(i, cm) }(index, clientMap)
				//log.Logger.Info(fmt.Sprintf("[getfangphone]  重复请求还是没有数据：%v", clientMap))
				break
			}
		}
	}
	f.result <- false
	//log.Logger.Error(fmt.Sprintf("[getfangphone] 最后也没有获取到数据 第%d代理池，ok:%v 结果是啥：%v,", index, ok, resp))
	return
}

func (f *fangInfoPhone) transformSend(response *http.Response){
	if response.StatusCode == http.StatusOK {
		body, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Logger.Error(fmt.Sprintf("[getfangphone] [transformSend] responese 数据获取失败: %v",f.fanginfo))
			f.result<-false
			return
		}
		fangDesc := FangDesc{}
		err = json.Unmarshal(body, &fangDesc)
		if err != nil {
			log.Logger.Error(fmt.Sprintf("[getfangphone] [transformSend] json 数据解析失败: %v",f.fanginfo))
			f.result<-false
			return
		}
		f.result<-true
		f.send(fangDesc)
	}
	f.result<-false
	return
}

// 将数据发送给websocket 处理
func (f *fangInfoPhone) send(desc FangDesc){
	createtime,_ := strconv.ParseInt(f.fanginfo.Creattime,10,64)
	updatetime,_ := strconv.ParseInt(f.fanginfo.Updatetime,10,64)
	luupdatetime,_ := strconv.ParseInt(f.fanginfo.Lucupdatetime,10,64)

	var tel string
	if desc.CardInfo.Phone != ""{
		tel = desc.CardInfo.Phone
	} else{
		tel = desc.Brokerinfo.Telno
	}
	finfo := models.FangInfo{
		FangId:f.fanginfo.Id,
		Title:f.fanginfo.Title,
		Source:"365",
		Area:f.fanginfo.City,
		Url:fmt.Sprintf("http://%s.sell.house365.com/s_%s.html",f.fanginfo.City,f.fanginfo.Id),
		Contactor:f.fanginfo.Contactor,
		District:f.fanginfo.District,
		StreetName:f.fanginfo.StreetName,
		Blockname:f.fanginfo.Blockinfo.Blockname,
		Address:f.fanginfo.Blockinfo.Address,
		Fitment:f.fanginfo.Fitment,
		Floor:f.fanginfo.Floor,
		Totalfloor:f.fanginfo.Totalfloor,
		Price:f.fanginfo.Price,
		Telno: tel,
		Apartment: desc.CardInfo.Apartment,
		Buildarea: desc.CardInfo.Buildarea,
		Creattime_fang: time.Unix(createtime,0).Format("2006-01-02 15:04:05"),
		Updatetime_fang: time.Unix(updatetime,0).Format("2006-01-02 15:04:05"),
		Lucupdatetime_fang: time.Unix(luupdatetime,0).Format("2006-01-02 15:04:05"),
	}

	body ,err := json.Marshal(finfo)
	if err !=nil {
		log.Logger.Error(fmt.Sprintf("[getFangPhone] [send] 最后居然json 失败了，finfo:%v; err:%v",finfo,err))
		return
	}
	websocket.SendAll(body)
}


func (f *fangInfoPhone) drainBody(body io.ReadCloser) {
	defer body.Close()

	_, err := io.Copy(ioutil.Discard, io.LimitReader(body, 10))
	if err != nil {
		log.Logger.Error("Error reading response body: " + err.Error())
	}
}

func (f *fangInfoPhone) retryPolicy(resp *http.Response, err error) (bool) {
	if err != nil {
		return true
	}

	if resp.StatusCode == 0 || resp.StatusCode >= 500 {
		return true
	}
	return false
}



func NewfangInfoPhone(fanginfo FangInfo) *fangInfoPhone {
	//log.Logger.Info(fmt.Sprintf("创建了一个fangphone, fanginfo: %v",fanginfo))
	return &fangInfoPhone{fanginfo,make(chan bool,1)}
}
